package main

import (
	"bufio"
	"flag"
	"fmt"
	"net"
	"os"
	"sync"
)

var (
	mode = flag.String("mode", "server", "定义server或client.")
	addr = flag.String("addr", "127.0.0.1:8080", "定义默认监听的本机地址.")
)
var handconn = make(map[string]*net.Conn, 5) //申请客户端连接对象注册表
func main() {
	flag.Parse()
	switch *mode {
	case "server":
		server(*addr)
	case "client":
		client(*addr)
	}
}

//server端广播与收集信息
func server(serveraddr string) {
	fmt.Println("server:服务端准备就绪!")
	ln, err := net.Listen("tcp", serveraddr)
	if err != nil {
		fmt.Println(err)
		return
	}
	go input()
	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Println(err)
		}
		fmt.Println("\r"+"["+conn.RemoteAddr().String()+"]:", "上线了！")
		fmt.Print("请输入：")
		//注册连接
		handconn[conn.RemoteAddr().String()] = &conn
		go process(&conn)
	}
}

//server处理函数
func process(sonconn *net.Conn) {
	defer delete(handconn, (*sonconn).LocalAddr().String())
	defer (*sonconn).Close()
	sonreader := bufio.NewReader(*sonconn)
	for {
		data, err := sonreader.ReadString('\n')
		if err != nil {
			fmt.Println(err)
			break
		}
		switch data {
		case "exit\n":
			return
		case "quit\n":
			return
		default:
			fmt.Print("\r["+(*sonconn).RemoteAddr().String()+"]:", data)
			fmt.Print("请输入：")
		}
	}
}

//server输入函数
func input() {
	stdreader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("\r请输入：")
		stdata, err := stdreader.ReadString('\n')
		if err != nil {
			fmt.Println(err)
			break
		}
		fmt.Print("你输入的是：", stdata)
		for k, con := range handconn {
			_, err := (*con).Write([]byte(stdata))
			if err != nil {
				fmt.Println(err)
				delete(handconn, k)
				(*con).Close()
				continue
			}
		}
	}
}

//net客户端
func client(addr string) {
	fmt.Println("client:客户端准备就绪!")
	var wg sync.WaitGroup
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		fmt.Println(err)
		return
	}
	wg.Add(2)
	//向net.conn发送数据
	go func(con *net.Conn) {
		for {
			defer wg.Done()
			defer (*con).Close()
			fmt.Println("等待发送数据！")
			stdinreader := bufio.NewReader(os.Stdin)
			stdindata, err := stdinreader.ReadString('\n')
			if err != nil {
				fmt.Println(err)
				break
			}
			(*con).Write([]byte(stdindata))
			fmt.Print("你输入的是：", stdindata)
			if stdindata == "exit\n" {
				return
			}
		}
	}(&conn)
	//从net.conn获取数据
	go func(con *net.Conn) {
		defer wg.Done()
		defer (*con).Close()
		for {
			fmt.Println("等待接收数据！")
			conreader := bufio.NewReader(*con)
			condata, err := conreader.ReadString('\n')
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Print((*con).RemoteAddr(), "发送的数据：")
			fmt.Print(condata)
		}
	}(&conn)
	wg.Wait()
}
